﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Threading;
using Microsoft.Win32;
using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;

namespace VoiceTestPlatform
{
    public class ArtificialViewModel : ViewModelBase
    {
        System.Timers.Timer recordTimer = null;
        //Stopwatch sw;
        private string curRecordPath = null;
        public ArtificialViewModel()
        {
            recordTimer = new System.Timers.Timer(20 * 1000);
            recordTimer.Elapsed += recordTimer_Elapsed;
            IniCommands();
            Results = new ObservableCollection<TestResult>();
            ResultManager.ArtificialResults.CollectionChanged -= ResultItems_CollectionChanged;
            ResultManager.ArtificialResults.CollectionChanged += ResultItems_CollectionChanged;
            //sw = new Stopwatch();
        }

        void ResultItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add &&
                e.NewItems != null)
            {
                var temp = e.NewItems[0] as TestResult;
                if (temp != null && !string.IsNullOrEmpty(temp.Recognition))
                {
                    if (!string.IsNullOrEmpty(curRecordPath))
                    {
                        temp.BackSound = Path.GetFileName(curRecordPath);
                    }                   
                    Results.Add(temp);
                }

            }
        }

        void recordTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            //todo 
            string lastpath = curRecordPath;
            App.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
            {
                StopRecordInternal();
                //StopRecordCommandAction(null);

                //Thread.Sleep(1000);
                //StartRecordCommandAction(null);
            }));
            Thread.Sleep(100);
            App.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
            {
                StartRecordInternal();
                //StartRecordCommandAction(null);
            }));

            //处理已录音频

            HandleRecord(lastpath);
        }

        private void HandleRecord(string lastpath)
        {
            if (Results.Count > 0)
            {
                var last = Results.Last(rr => !string.IsNullOrEmpty(rr.Recognition));
                if (last != null &&
               !string.IsNullOrEmpty(last.BackSound) &&
               last.BackSound == Path.GetFileName(lastpath))
                {
                    string cd = ParameterManager.ArtificialPath;//System.IO.Directory.GetCurrentDirectory();
                    string sp = Path.Combine(cd, "TestSound");
                    if (!Directory.Exists(sp))
                    {
                        Directory.CreateDirectory(sp);
                    }
                    string df = Path.Combine(sp, Path.GetFileName(lastpath));
                    File.Move(lastpath, df);
                }
                else
                {
                    try
                    {
                        File.Delete(lastpath);
                    }
                    catch (Exception)
                    {

                        //throw;
                    }

                }
            }
            else
            {
                try
                {
                    File.Delete(lastpath);
                }
                catch (Exception)
                {

                    //throw;
                }
            }
        }

        private void IniCommands()
        {
            StartRecordCommand = new DelegateCommand(StartRecordCommandAction);
            StopRecordCommand = new DelegateCommand(StopRecordCommandAction);
            ResultToExcelCommand = new DelegateCommand(ResultToExcelCommandAcition);
            SavePortMsgCommand = new DelegateCommand(SavePortMsgCommandAction);
            ClearResultCommand = new DelegateCommand(ClearResultCommandAction);
        }
        private void ClearResultCommandAction(object obj)
        {
            ResultManager.ArtificialResults.Clear();
        }

        private void SavePortMsgCommandAction(object obj)
        {
            string ReceiveText = SerialPortHelper.SerialPortString.ToString();
            if (string.IsNullOrEmpty(ReceiveText))
            {
                System.Windows.Forms.MessageBox.Show("原消息为空");
                return;
            }
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.InitialDirectory = ParameterManager.RunDir;
            sfd.FileName = "全部原消息" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".txt";
            sfd.Filter = "(*.txt)|*.txt|(*.*)|*.*";
            sfd.AddExtension = true;
            sfd.RestoreDirectory = true;
            if (sfd.ShowDialog() == true)
            {
                //textBox2.Text = sfd.FileName;
                FileStream fs = new FileStream(sfd.FileName, FileMode.Create);
                StreamWriter sw = new StreamWriter(fs);
                try
                {
                    sw.Write(ReceiveText);
                    sw.Flush();
                }
                catch (Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show(ex.Message.ToString());
                }
                finally
                {
                    sw.Close();
                    fs.Close();
                }
            }
        }

        private void ResultToExcelCommandAcition(object obj)
        {
            const string extension = "xls";
            var fileName = "人工测试结果" + DateTime.Now.ToString("yyyyMMddHHmmss");
            var dialog = new SaveFileDialog
            {
                DefaultExt = extension,
                Filter = string.Format("{1} files (*.{0})|*.{0}|All files (*.*)|*.*", extension, "Excel"),
                FilterIndex = 1,
                FileName = fileName,
            };
            if (dialog.ShowDialog() != true) return;
            try
            {
                using (var stream = dialog.OpenFile())
                {
                    //stream.e
                    // ExportExcelAll(stream, gridView);
                    var hssfworkbook = new HSSFWorkbook(); //创建文件
                    var dsi = PropertySetFactory.CreateDocumentSummaryInformation();
                    dsi.Company = "广东美的集团公司";
                    hssfworkbook.DocumentSummaryInformation = dsi;
                    var si = PropertySetFactory.CreateSummaryInformation();
                    si.Subject = "本文件由语音测试系统导出";
                    hssfworkbook.SummaryInformation = si;
                    var sheet1 = hssfworkbook.CreateSheet("结果明细");

                    //创建表头
                    var headerRow = sheet1.CreateRow(0);
                    var dataColumns = new List<string>() { "时间", "录音","识别" ,
                    "距离", "角度", "噪音背景"};
                    // var dataColumns = new List<string>() { "时间", "录音","识别", "音频命令", "相关音频" ,
                    //"识别用时"};
                    for (var i = 0; i < dataColumns.Count(); i++)
                    {
                        headerRow.CreateCell(i).SetCellValue(dataColumns[i]);
                    }

                    int dataindex = 1;
                    var rs = ResultManager.ArtificialResults.ToList();
                    string cd = ParameterManager.ArtificialPath;
                    string sp = Path.Combine(cd, "TestSound");
                   // WindowsService.ShowMessageBox(sp);
                    foreach (var item in rs)
                    {
                        var deRow = sheet1.CreateRow(dataindex);
                        dataindex++;
                        deRow.CreateCell(0).SetCellValue(item.TestDate);
                        //deRow.CreateCell(1).SetCellValue(item.ResultText);
                        var cell1 = deRow.CreateCell(1) as HSSFCell;
                        if (!string.IsNullOrEmpty(item.BackSound))
                        {
                            HSSFHyperlink link = new HSSFHyperlink(HyperlinkType.FILE);
                            var tempAddress = Path.Combine(sp, item.BackSound);
                            /// 转码，否则中文路径会乱码
                            byte[] srcBytes = Encoding.Default.GetBytes(tempAddress);
                            string strPath = Encoding.GetEncoding("ISO-8859-1").GetString(srcBytes);
                            ///
                            //WindowsService.ShowMessageBox(strPath);
                            link.Address = strPath;
                           
                            cell1.Hyperlink = link;
                        }
                        cell1.SetCellValue(item.BackSound);

                        deRow.CreateCell(2).SetCellValue(item.Recognition);
                        //deRow.CreateCell(3).SetCellValue(item.AudioCommand);

                        //var cell4 = deRow.CreateCell(4) as HSSFCell;
                        //cell4.SetCellValue(item.Audio);//相关音频

                        deRow.CreateCell(3).SetCellValue(item.DistanceText);//距离
                        deRow.CreateCell(4).SetCellValue(item.AngelText);
                        deRow.CreateCell(5).SetCellValue(item.NoiseText);
                        //deRow.CreateCell(8).SetCellValue(item.RecognitionTimeString);//识别用时
                    }


                    //dataindex++;
                    //var stRow = sheet1.CreateRow(dataindex);
                    //stRow.CreateCell(0).SetCellValue("开始时间");
                    //stRow.CreateCell(1).SetCellValue(StartRecordTime);

                    //dataindex++;
                    //stRow = sheet1.CreateRow(dataindex);
                    //stRow.CreateCell(0).SetCellValue("结束时间");
                    //stRow.CreateCell(1).SetCellValue(StopRecordTime);

                    //dataindex++;
                    //stRow = sheet1.CreateRow(dataindex);
                    //stRow.CreateCell(0).SetCellValue("测试用时");
                    //string time = string.Empty;
                    //if (startTime != null)
                    //{
                    //    DateTime end = endTime == null ? DateTime.Now : endTime.Value;
                    //    TimeSpan ts = end - startTime.Value;
                    //    time = string.Format("{0}小时{1}分{2}秒", ts.Hours, ts.Minutes, ts.Seconds);
                    //}
                    //stRow.CreateCell(1).SetCellValue(time);


                    dataindex++;
                    var stRow = sheet1.CreateRow(dataindex);
                    stRow.CreateCell(0).SetCellValue("人工测试次数");
                    if (Results != null)
                    {
                        stRow.CreateCell(1).SetCellValue(Results.Count.ToString());
                    }

                    hssfworkbook.Write(stream); //写入文件流
                }
            }
            catch (IOException ex)
            {
                //MessageBox.Show(string.Format("文件\"{0}\"已打开，请关闭后再点击导出！\n{1}", dialog.FileName, ex.Message), "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
        }

        DateTime? startTime = null;
        DateTime? endTime = null;

        private void StopRecordCommandAction(object obj)
        {
            StopRecordInternal();
            IsStartEnable = true;
            StopRecordTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
            endTime = DateTime.Now;
            HandleRecord(curRecordPath);
        }



        private void StopRecordInternal()
        {
            recordTimer.Stop();
            SoundManager.StopRecord();
        }

        private void StartRecordCommandAction(object obj)
        {
            if (!SerialPortHelper.Instance.IsPortOpened)
            {
                WindowsService.ShowMessageBox("串口没打开，请打开后再试");
                return;
            }
            //ResultManager.ArtificialResults.Clear();

            StartRecordInternal();
            IsStartEnable = false;
            StartRecordTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
            StopRecordTime = string.Empty;
            startTime = DateTime.Now;
            endTime = null;

        }

        private void StartRecordInternal()
        {
            string filename = DateTime.Now.ToString("yyyyMMddHHmmss") + ".wav";
            curRecordPath = SoundManager.StartTestRecord(filename);
            recordTimer.Start();
        }

        public DelegateCommand StartRecordCommand { get; set; }
        public DelegateCommand StopRecordCommand { get; set; }
        public DelegateCommand ResultToExcelCommand { get; set; }
        public DelegateCommand SavePortMsgCommand { get; set; }
        public DelegateCommand ClearResultCommand { get; set; }
        

        private ObservableCollection<TestResult> results;

        public ObservableCollection<TestResult> Results
        {
            get { return results; }
            private set { results = value; RaisePropertyChanged("Results"); }
        }

        #region ui
        private bool isStartEnable = true;
        public bool IsStartEnable
        {
            get { return isStartEnable; }
            set
            {
                isStartEnable = value;
                RaisePropertyChanged("IsStartEnable");
                RaisePropertyChanged("IsStopEnable");
            }
        }

        public bool IsStopEnable
        {
            get { return !IsStartEnable; }
        }

        #endregion

        private string startRecordTime;
        public string StartRecordTime
        {
            get { return startRecordTime; }
            set
            {
                startRecordTime = value;
                RaisePropertyChanged("StartRecordTime");
            }
        }

        private string stopRecordTime;
        public string StopRecordTime
        {
            get { return stopRecordTime; }
            set
            {
                stopRecordTime = value;
                RaisePropertyChanged("StopRecordTime");
            }
        }
    }
}
